{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 使用梯度上升法求解主成分"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "X = np.empty((100,2))\n",
    "X[:,0] = np.random.uniform(0., 100., size=100)\n",
    "X[:,1] = 0.75 * X[:,0] + 3. + np.random.normal(0., 10., size=100)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.collections.PathCollection at 0x7f7eb3235590>"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.scatter(X[:,0], X[:,1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "41.971274144826424"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X[:,1].mean()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "100"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "len(X)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### demean"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "def demean(X):\n",
    "    return X - np.mean(X, axis=0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "X_demean = demean(X)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.collections.PathCollection at 0x7f7eb3667410>"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.scatter(X_demean[:,0], X_demean[:,1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "8.384404281969182e-15"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.mean(X_demean[:,0])  #第0行均值已归零"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "7.389644451905042e-15"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.mean(X_demean[:,1])  #第1行均值已归零"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 梯度上升法"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "def f(w, X):\n",
    "    return np.sum((X.dot(w)**2)) / len(X)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "def df_math(w, X):\n",
    "    return X.T.dot(X.dot(w)) * 2. / len(X)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "def df_debug(w, X, epsilon=1e-10):\n",
    "    res = np.empty(len(w))\n",
    "    for i in range(len(w)):\n",
    "        w_1 = w.copy()\n",
    "        w_1[i] += epsilon\n",
    "        w_2 = w.copy()\n",
    "        w_2[i] -= epsilon\n",
    "        res[i] = (f(w_1, X) - f(w_2, X)) / (2. * epsilon)\n",
    "    \n",
    "    return res\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([3, 4, 5])"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.array([1,2,3]) + 2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [],
   "source": [
    "def direction(w):\n",
    "    return w / np.linalg.norm(w)\n",
    "\n",
    "def gradient_ascent(df, X, initial_w, eta, n_iters=1e4, epsilon=1e-8):\n",
    "    cur_iter = 0 \n",
    "    w = direction(initial_w)\n",
    "    \n",
    "    while cur_iter < n_iters:\n",
    "        gradient = df(w, X)\n",
    "        last_w = w\n",
    "        w = w + eta * gradient\n",
    "        w = direction(w)   # 注意：每次都要求一个单位方向，因此需要用w除以它的模\n",
    "        if (abs(f(w, X) - f(last_w, X)) < epsilon):\n",
    "            break\n",
    "            \n",
    "        cur_iter += 1\n",
    "            \n",
    "    return w"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [],
   "source": [
    "initial_w = np.random.random(X.shape[1])     # 注意：初始化的w值不能为0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0.97271335, 0.21439046])"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "initial_w"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [],
   "source": [
    "eta = 0.001"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0.78672281, 0.61730642])"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 注意： 不能使用StandardScaler标准化数据\n",
    "gradient_ascent(df_debug, X_demean, initial_w, eta)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [],
   "source": [
    "w = gradient_ascent(df_math, X_demean, initial_w, eta)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[<matplotlib.lines.Line2D at 0x7f7eb2815e90>]"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.scatter(X_demean[:,0],X_demean[:,1])\n",
    "plt.plot([-50, w[0]*60], [-50,w[1]*60], color='r')    # 理想的轴，即所有样本投射到这个轴上时的映射点方差最大，\n",
    "# 由于是第一个求出来的主成分，因此也称之为 第一主成分"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(100, 2)"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X_demean.shape"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 随机梯度上升法"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 78,
   "metadata": {},
   "outputs": [],
   "source": [
    "def f_2(w, X_i):\n",
    "    return np.sum((X_i.dot(w)**2)) / len(X_i)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 80,
   "metadata": {},
   "outputs": [],
   "source": [
    "def df_sga(w, X_i):\n",
    "    return (X_i.T.dot(X_i.dot(w))) * 2. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [],
   "source": [
    "def direction_2(w):\n",
    "    return w / np.linalg.norm(w)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 95,
   "metadata": {},
   "outputs": [],
   "source": [
    "def sga(df, X, initial_w, n_iters=5, t0=5, t1=50):\n",
    "\n",
    "    def learning_rate(t):\n",
    "        return t0 / (t + t1)\n",
    "    \n",
    "    w = direction_2(initial_w)\n",
    "    cur_iter = 0\n",
    "    m = len(X)\n",
    "    \n",
    "    for  cur_iter in range(n_iters):\n",
    "        \n",
    "        indexes = np.random.permutation(np.arange(m))\n",
    "        X_new = X[indexes]\n",
    "        \n",
    "        for i in range(m):\n",
    "            gradient = df_sga(w, X_new[i])\n",
    "            w = w + learning_rate((cur_iter * m +i)) * gradient\n",
    "            w = direction_2(w)\n",
    "        \n",
    "    return w"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [],
   "source": [
    "initial_w = np.random.random(X.shape[1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 125,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0.77173426, 0.63594515])"
      ]
     },
     "execution_count": 125,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sga(df_sga, X, initial_w, n_iters=1000)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0.78672201, 0.61730744])"
      ]
     },
     "execution_count": 47,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "gradient_ascent(df_math, X_demean, initial_w, eta)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 121,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[<matplotlib.lines.Line2D at 0x7f7eb1b79510>]"
      ]
     },
     "execution_count": 121,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.scatter(X_demean[:,0],X_demean[:,1])\n",
    "plt.plot([-50, sga(df_sga, X, initial_w, n_iters=1000)[0]*60], [-50,sga(df_sga, X, initial_w, n_iters=100)[1]*60],\n",
    "         color='r') "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 92,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([44.05568621, 43.4078821 ])"
      ]
     },
     "execution_count": 92,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 小批量梯度上升法"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
